package com.patni.frame.util;

import java.awt.Color;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class MyScrollPane extends JLabel {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final int barWidth = 15;
	private JPanel bar;
	private JPanel barTop;
	private JPanel barMiddle;
	private JPanel barBottom;
	private JComponent jc;
	private int tempy1 = 0;
	private int tempy2 = 0;
	private int X;
	private int Y;
	private int barMH;
	private boolean toTop;
	private boolean toDown;

	private int Mdh;
	private int Mdy;
	private boolean barPressed_isPressd;
	private int barPressed_Type;
	private boolean barPressed_f;
	private Timer barPressed_timer = new Timer();
	private boolean isWheelMoved;
	private int WheelMovedTime;
	private Timer WheelMoved_timer = new Timer();

	public MyScrollPane(JComponent jc) {
		this.setLayout(null);

		this.jc = jc;

		bar = new JPanel();
		barTop = new JPanel();
		barMiddle = new JPanel();
		barBottom = new JPanel();
		bar.setLayout(null);
		barTop.setLayout(null);
		barMiddle.setLayout(null);
		barBottom.setLayout(null);

		barMiddle.setBackground(new Color(209, 228, 237));
		barTop.setBackground(new Color(209, 228, 237));
		barBottom.setBackground(new Color(209, 228, 237));

		barResize();

		barTop.add(MyScrollIcon.getud(0, 0));

		barBottom.add(MyScrollIcon.getud(0, 1));

		bar.add(barTop);
		bar.add(barMiddle);
		bar.add(barBottom);

		this.add(bar);
		this.add(jc);

		this.addComponentListener(new ComponentListener() {

			@Override
			public void componentHidden(ComponentEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void componentMoved(ComponentEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void componentResized(ComponentEvent e) {
				// TODO Auto-generated method stub
				barResize();
			}

			@Override
			public void componentShown(ComponentEvent e) {
				// TODO Auto-generated method stub

			}
		});

		this.addMouseWheelListener(new MouseWheelListener() {

			@Override
			public void mouseWheelMoved(MouseWheelEvent e) {
				// TODO Auto-generated method stub
				WheelMovedImpl(e.getWheelRotation());
//				System.out.println("MouseWheelListener");
			}

		});

		jc.addComponentListener(new ComponentListener() {

			@Override
			public void componentHidden(ComponentEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void componentMoved(ComponentEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void componentResized(ComponentEvent e) {
				// TODO Auto-generated method stub
				barResize();
				System.out.println("Myscrollpane size change");
			}

			@Override
			public void componentShown(ComponentEvent e) {
				// TODO Auto-generated method stub

			}

		});

		barMiddle.addMouseMotionListener(new MouseMotionListener() {

			@Override
			public void mouseDragged(MouseEvent e) {
				// TODO Auto-generated method stub
				tempy2 = e.getY();
				X = barMiddle.getX();
				Y = barMiddle.getY();
				barMH = barMiddle.getHeight();

				int tempY = tempy2 - tempy1;
				toTop = true;
				toDown = true;

				if (Y <= MyScrollPane.this.barWidth) {
					toTop = false;
				} else if (Y >= bar.getHeight() - MyScrollPane.this.barWidth
						- barMH) {
					toDown = false;
				}

				if (!toTop && tempY < 0) {
					barMiddle.setLocation(X, MyScrollPane.this.barWidth);
					setBodyLocation(MyScrollPane.this.barWidth);
				} else if (!toDown && tempY > 0) {
					barMiddle.setLocation(X, bar.getHeight()
							- MyScrollPane.this.barWidth - barMH);
					setBodyLocation(bar.getHeight()
							- MyScrollPane.this.barWidth - barMH);
				} else {
					barMiddle.setLocation(X, Y + tempY);
					setBodyLocation(Y + tempY);
				}

			}

			@Override
			public void mouseMoved(MouseEvent e) {
				// TODO Auto-generated method stub
				tempy1 = e.getY();
			}

		});

		barMiddle.addMouseListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub
				if (!barPressed_isPressd)
					barMiddle.setBackground(new Color(210, 234, 246));

			}

			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub
				if (!barPressed_isPressd)
					barMiddle.setBackground(new Color(209, 228, 237));

			}

			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
				barPressed_isPressd = true;
				barMiddle.setBackground(new Color(185, 217, 232));

			}

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				barPressed_isPressd = false;
				barMiddle.setBackground(new Color(209, 228, 237));

			}

		});

		barTop.addMouseListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub

				barTop.add(MyScrollIcon.getud(1, 0));
				barTop.repaint();
				barPressed(0);
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub

				barTop.add(MyScrollIcon.getud(0, 0));
				barTop.repaint();
				barReleased();
			}

		});

		barBottom.addMouseListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseEntered(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mouseExited(MouseEvent e) {
				// TODO Auto-generated method stub

			}

			@Override
			public void mousePressed(MouseEvent e) {
				// TODO Auto-generated method stub
				barBottom.add(MyScrollIcon.getud(1, 1));
				barBottom.repaint();
				barPressed(1);
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				// TODO Auto-generated method stub
				barBottom.add(MyScrollIcon.getud(0, 1));
				barBottom.repaint();
				barReleased();
			}

		});

	}

	public void setBodyLocation(int Mdy) {
		jc.setLocation(jc.getX(), -(Mdy - barWidth) * (jc.getHeight())
				/ (bar.getHeight() - barWidth * 2));
	}

	public void setMdLocation() {
		if (jc.getHeight() > bar.getHeight())
			Mdy = (bar.getHeight() - 2 * barWidth) * (jc.getY())
					/ jc.getHeight() + barWidth;
	}

	public void setMdHeight() {
		if (jc.getHeight() > bar.getHeight())
			Mdh = (bar.getHeight() * (bar.getHeight() - 2 * barWidth))
					/ jc.getHeight();
		else
			Mdh = 0;
	}

	public void barPressed(int type) {
		this.barPressed_Type = type;
		this.barPressed_f = true;
		barPressedImpl();
	}

	public void barReleased() {
		this.barPressed_f = false;
	}

	public void barPressedImpl() {

		barPressed_timer.schedule(new TimerTask() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				if (barPressed_Type == 0) {
					int y = barMiddle.getY();
					if (y > barWidth) {
						int yy = y - 2;
						barMiddle.setBounds(0, yy, barWidth, Mdh);
						setBodyLocation(yy);
					}
				} else if (barPressed_Type == 1) {
					int y = barMiddle.getY();
					if (y < bar.getHeight() - barWidth - barMiddle.getHeight()) {
						int yy = y + 2;
						barMiddle.setBounds(0, yy, barWidth, Mdh);
						setBodyLocation(yy);
					}
				}
				
				jc.repaint();
//				System.out.println("barPressed_Type:"+barPressed_Type);
				
//				if (barPressed_Type == 0) {
//					int y = jc.getY();
//					System.out.println("&&&&&&&&&&&"+y);
//					if (y <= 0) {
//						int yy = y + 2;
//					
//						jc.setLocation(jc.getX(), yy);
//						
//						setMdLocation();
//						barMiddle.setLocation(0, Mdy);
//					}
//				} else if (barPressed_Type == 1) {
//					int y = jc.getY();
//					System.out.println("&&&*&&&&&&"+y);
//					if (y >= -jc.getY() - jc.getHeight()) {
//						int yy = y - 2;
//						
//						
//						jc.setLocation(jc.getX(), yy);
//						
//						setMdLocation();
//						barMiddle.setLocation(0, Mdy);
//					}
//				}
				
				
				if (barPressed_f) {
					barPressedImpl();
				}
			}

		}, 10);

	}

	public void WheelMovedImpl(int rota) {

		if (!isWheelMoved) {
			isWheelMoved = true;
			this.WheelMovedTime = 10;
			barPressed(rota > 0 ? 1 : 0);
			wheelMoveTimerIpml();
		} else {
			this.WheelMovedTime = 10;
		}

	}

	public void wheelMoveTimerIpml() {
		this.WheelMoved_timer.schedule(new TimerTask() {
			@Override
			public void run() {
				if (WheelMovedTime == 0) {
					barReleased();
					isWheelMoved = false;
				} else {
					wheelMoveTimerIpml();
				}
				WheelMovedTime--;
			}
		}, 10);
	}

	public void barResize() {
		bar
				.setBounds(this.getWidth() - barWidth, 0, barWidth, this
						.getHeight());
		barTop.setBounds(0, 0, barWidth, barWidth);
		barBottom.setBounds(0, this.getHeight() - barWidth, barWidth, barWidth);

		setMdHeight();
		setMdLocation();

		if (Mdh > 0)
			barMiddle.setBounds(0, Mdy, barWidth, Mdh);
		else
			bar.setSize(0, 0);
	}
}
